iT邦幫忙

2021 iThome 鐵人賽

DAY 9
0

資料綁定

datum()函式

前面的文章多半是在使用D3來操作DOM,這邊主要探討D3的核心,將資料綁定在DOM的元素中,換句話說DOM的元素樣貌可以透過資料來改變,例如當資料數值是比較大的情況時,你所繪製的div或是svgcircle半徑也隨之變大。

先看以下範例

首先我們先創建一個陣列,然後使用for迴圈以陣列長度作為迴圈數,之後依序添加div這邊有一個特別的datum()函式,我們嘗試著將每一筆的陣列內容放入函式當中當作參數,最後加入text()函式在其中放入一個回呼函式參數加入d並且return出來就可以看到畫面呈現。

const arr = [7,2,5,4,13];
for(let i=0; i<arr.length; i++){    
  d3.select("body")
  .append("div")
  .datum(arr[i])
  .text(function(d){
      return d;
  })
}

畫面呈現如下圖
https://ithelp.ithome.com.tw/upload/images/20210924/20125095uELbaAzEu8.png
這時候可以發現在添加的div透過datum()綁定上去了,你可以嘗試著將上述第5行的 .datum(arr[i])註解掉應該會發現網頁畫面的數字不見了。另一個方式你可以撰寫console.log印出裡面的div包含的data訊息

程式碼如下

const arr = [7,2,5,4,13];
  for(let i=0; i<arr.length; i++){    
    d3.select("body")
    .append("div")
    .datum(arr[i])
    .text(function(d){
        return d;
    })
  }
const allDataInDiv = d3.select("body").selectAll("div")["_groups"][0];
  for(let i=0; i<allDataInDiv.length;i++){
      console.log(allDataInDiv[i]);
}

開啟開發人員工具可以發現div被添加了__data__在裡面,如下圖

https://ithelp.ithome.com.tw/upload/images/20210924/20125095V0w7dY9D25.png

所以我們才可以透過text()回呼函式來獲得d參數,而d所表示的就是資料的意思

data()函式

查看以下程式碼我們預先在body撰寫空的div,這次使用selectAll來一次選取所有的div並且改用data()放入整個陣列,此時一樣可以達到之前所用datum()範例所創立的樣貌,因此可以這麼理解是data()將陣列的各項分別綁定到選擇的各元素

<body>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
  <script>
     const arr = [7,2,5,4,13];
     d3.select("body")
     .selectAll("div")
     .data(arr)
     .text(function(d){ return d});
  </script>
</body>

data()和datum比較

datum的差異你可以將.data(arr)換成.datum(arr)之後看畫面呈現更能看得出其中的奧妙

<body>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>

  <script>
    let arr = [7,2,5,4,13];
    d3.select("body")
    .selectAll("div")
    .datum(arr)
    .text(function(d){ return d});
  </script>
</body>

此時你會看到如下圖,datum()會直接將整個陣列綁在每一個div上面,多半我們在處理資料的時候會使用data()來綁定較為容易。
https://ithelp.ithome.com.tw/upload/images/20210924/201250953XZ4zvoJCq.png

透過函式將樣式改變

若我們希望在大於6的數值就呈現紅色的話,我們透過style()操作它的樣式,由於已經綁定資料在元素上,因此我們一樣可以在第二個參數帶入d承接資料並透過if來判斷大於6的函式return紅色

const arr = [7,2,5,4,13];
   d3.select("body")
   .selectAll("div")
   .data(arr)
   .text(function(d,i,n){ 
     return d;
    })
    .style(
        "color",function(d){
        if(d>6){
            return "red";
        }
    });

結果呈現如下圖
https://ithelp.ithome.com.tw/upload/images/20210924/20125095Upvjt11xog.png

關於data和text的函式的其他說明

text()函式介紹

text在綁定之後 函數 可以擁有三個參數,第一個參數是d表示data的意思,第二個參數是i表示陣列的索引值,第三個參數表示當前綁定的群組節點

你可以將下列程式碼執行看看並且開啟開發者人員工具。

<body>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <script>
     const arr = [7,2,5,4,13];
     d3.select("body")
     .selectAll("div")
     .data(arr)
     .text(function(d,i,n){ 
         console.log(d);
         console.log(i);
         console.log(n);
    });
  </script>
</body>

這邊擷取第一次迴圈所呈現的圖片,7表示陣列第一筆資料,0表示index索引值,最後的n表示當前綁定的元素節點
https://ithelp.ithome.com.tw/upload/images/20210924/20125095sstZV8Y8VB.png

參考官方textAPI說明

另外data()datum沒有帶入參數的時候可以得到綁定的數據
下面程式碼以data()為例

const arr = [7,2,5,4,13];
   d3.select("body")
   .selectAll("div")
   .data(arr)
   .text(function(d,i,n){ 
     return d;
});
console.log(    d3.select("body")
   .selectAll("div")
   .data());

或是以datum()為例

let arr = [7,2,5,4,13];
   d3.select("body")
   .selectAll("div")
   .data(arr)
   .text(function(d,i,n){ 
     return d;
});
console.log(
    d3.select("body")
   .select("div")
   .datum()
);

以上就是關於資料綁定的部分 下一篇將會介紹關於資料綁定時候需要注意的細節。


上一篇
D3JsDay08做為視覺化圖表的燃料,從網路擷取檔案的資料—fetch Data
下一篇
D3JsDay10 遇到元素資料不相等,用函式解決高人一等
系列文
從原料到燃料,從資料到預料—資料駕馭網頁之理科的美學30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言